package cn.tedu.mimall.product.repo.impl;

import cn.tedu.mimall.product.pojo.vo.ProductListItemVO;
import cn.tedu.mimall.product.pojo.vo.ProductStandardVO;
import cn.tedu.mimall.product.repo.IProductRedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Slf4j
@Repository
public class ProductRedisRepository implements IProductRedisRepository {
    @Autowired
    RedisTemplate<String, Serializable> redisTemplate;

    @Override
    public void save(ProductStandardVO productStandardVO) {
        log.debug("准备向Redis中写入数据:{}", productStandardVO);
        String key = getItemKey(productStandardVO.getId());
        redisTemplate.opsForSet().add(getAllKeysKey(), key);
        redisTemplate.opsForValue().set(key, productStandardVO);
    }

    @Override
    public void save(List<ProductListItemVO> products) {
        String key = getListKey();
        ListOperations<String, Serializable> ops = redisTemplate.opsForList();
        for (ProductListItemVO product : products) {
            ops.rightPush(key, product);
        }
    }

    @Override
    public ProductStandardVO get(Long id) {
        String key = getItemKey(id);
        Serializable serializable = redisTemplate.opsForValue().get(key);
        if (serializable != null) {
            if (serializable instanceof ProductStandardVO) {
                return (ProductStandardVO) serializable;
            }
        }
        return null;
    }

    @Override
    public List<ProductListItemVO> list() {
        long start = 0;
        long end = -1;
        return list(start, end);
    }

    @Override
    public List<ProductListItemVO> list(long start, long end) {
        String key = getListKey();
        ListOperations<String, Serializable> ops = redisTemplate.opsForList();
        List<Serializable> list = ops.range(key, start, end);
        List<ProductListItemVO> products = new ArrayList<>();
        for (Serializable item : list) {
            products.add((ProductListItemVO) item);
        }
        return products;
    }

    @Override
    public Long deleteAll() {
        Set<String> allKeys = getAllKeys();
        return redisTemplate.delete(allKeys);
    }

    private String getItemKey(Long id) {
        return PRODUCT_ITEM_KEY_PREFIX + id;
    }

    private String getListKey() {
        return PRODUCT_LIST_KEY;
    }

    private String getAllKeysKey() {
        return PRODUCT_ALL_KEYS_KEY;
    }

    private Set<String> getAllKeys() {
        // return redisTemplate.keys(BRAND_KEY_PREFIX + "*");
        Set<Serializable> members = redisTemplate.opsForSet().members(getAllKeysKey());
        Set<String> keys = new HashSet<>();
        for (Serializable member : members) {
            keys.add((String) member);
        }
        return keys;
    }
}
